package main //建议包名与文件夹同名，main一般是程序的入口包,一般main函数都会放在这个包下
import "fmt"

//33集完
func test1(num int){
     num=30
	 fmt.Println("test1函数中",num)
} 
//*int 参数的类型为指针
func test2(num *int){
	*num=30
	fmt.Println("test2函数中",*num)
} 
//函数中类型可以是函数 可以通过方法名直接调用传过来的函数：参数名 func(参数类型)
func test3(num1 int,num2 float32,testFunc func(int)){
	fmt.Println("test3函数中")
	testFunc(num1)
}

//在test3的基础上优化
type myFunc func(int)
func test4(num1 int,num2 float32,testFunc myFunc){
	fmt.Println("test4函数中")
	testFunc(num1)
}

//返回值升级写法，将返回值命名返回，不需要对应返回顺序
func cal(num1 int,num2 int)(sum int,sub int){
    sum = num1 + num2
	sub = num1 - num2
	return 	
} 


func main(){
	/*注：
	    【1】基本数据类型和数组都是值传递，即进行值拷贝，在函数内部修改，不影响函数外原来的值
	    【2】以值传递的数据类型如果想要在函数内部修改函数外的变量，可以传入变量的地址&，函数内以指针的方式操作变量，从效果来看与引用类型一致
	*/
	 var num int=10
	 test1(num)
	 fmt.Println("test函数外",num)
	 test2(&num)
	 fmt.Println("test函数外",num)

	 //传函数类型值
     test3(10,3.19,test1)

	 //自定义类型
	 type myInt int 
	 var myTypeNum myInt=30
	 fmt.Printf("我的别名类型为：%T，值为%v\n",myTypeNum,myTypeNum)
	 //直接赋值不是同一类型会报错，若要将自定义的myInt类型的num值转为int，可以强转
     var num1 int=int(myTypeNum)
	 fmt.Println("转为int后的值为",num1)

	 //自定义类型传函数值
	 test4(20,4.5,test1)

	 sum,sub := cal(30,20)
	 fmt.Println("sum=",sum,"sub=",sub)
}